package com.sy.utils;

import com.alibaba.fastjson.JSON;
import com.sy.constant.Scope;
import com.sy.dto.JsonResult;
import com.sy.entity.User;
import org.apache.commons.lang3.ArrayUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.servlet.ServletContext;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.io.PrintWriter;

import static com.sy.constant.BusinessConstant.COOKIE_MIN_AGE;
import static com.sy.constant.BusinessConstant.COOKIE_TOKEN_NAME;
import static com.sy.constant.BusinessConstant.REDIS_USER_PREFIX;

@Component
public class HttpUtils {
    @Autowired
    private RedisClient redisClient;
    @Autowired
    private HttpUtils httpUtils;

    private HttpUtils() {

    }


    /**
     * 构建失败情况下要返回给前端的JSON对应的对象
     *
     * @param errMsg 错误信息
     * @return 错误时的JSON对应的对象
     */
    public JsonResult buildFailure(Integer code, String errMsg) {
        JsonResult jsonResult = new JsonResult();
        jsonResult.setCode(code);
        jsonResult.setErrMsg(errMsg);
        return jsonResult;
    }

    /**
     * 构建成功情况下要返回给前端的JSON对应的对象
     *
     * @param data 要返回给前端的数据
     * @return 成功时的JSON对应的对象
     */
    public JsonResult buildSuccess(Integer code, Object... data) {
        JsonResult jsonResult = new JsonResult();
        jsonResult.setCode(code);
        if (null != data && data.length != 0) {
            jsonResult.setData(data[0]);
        }
        return jsonResult;
    }

    /**
     * 用于写出JSON字符串到客户端
     *
     * @param res  响应对象
     * @param data 要转换为JSON的对象
     * @throws IOException
     */
    public void writeJson(HttpServletResponse res, Object data) throws IOException {
        res.setContentType("application/json;charset=utf-8");
        PrintWriter pw = res.getWriter();
        pw.print(JSON.toJSONString(data));
    }

    /**
     * 为request、session、ServletContext等对象进行统一赋值的操作
     *
     * @param name  属性名
     * @param value 属性值
     * @param scope 作用域
     */
    public void setAttribute(String name, Object value, Scope scope) {
        HttpServletRequest req = ServletHolderUtils.getCurRequest();
        HttpSession session = req.getSession();
        ServletContext sc = req.getServletContext();
        if (scope == Scope.REQUEST) {
            req.setAttribute(name, value);
        }
        if (scope == Scope.SESSION) {
            session.setAttribute(name, value);
        }
        if (scope == Scope.SERVLET_CONTEXT) {
            sc.setAttribute(name, value);
        }
    }

    /**
     * 从request、session、ServletContext等对象中获取属性值
     *
     * @param name  属性名
     * @param scope 作用域
     */
    public <T> T getAttribute(String name, Scope scope) {
        HttpServletRequest req = ServletHolderUtils.getCurRequest();
        HttpSession session = req.getSession();
        ServletContext sc = req.getServletContext();
        Object obj = null;
        if (scope == Scope.REQUEST) {
            obj = req.getAttribute(name);
        }
        if (scope == Scope.SESSION) {
            obj = session.getAttribute(name);
        }
        if (scope == Scope.SERVLET_CONTEXT) {
            obj = sc.getAttribute(name);
        }
        if (null == obj) {
            return null;
        } else {
            return (T) obj;
        }
    }

    /**
     * 写入Cookie
     *
     * @param name  名字
     * @param value 值
     * @param age   生存时间
     */
    public void addCookie(String name, String value, int age) {
        HttpServletResponse res = ServletHolderUtils.getCurResponse();
        Cookie cookie = new Cookie(name, value);
        cookie.setPath("/");
        cookie.setMaxAge(age);
        res.addCookie(cookie);
    }

    /**
     * 根据Cookie的名字获取Cookie的值
     *
     * @param name Cookie的名字
     * @return Cookie的值
     */
    public String getCookie(String name) {
        Cookie[] cookies = ServletHolderUtils.getCurRequest().getCookies();
        if (!ArrayUtils.isEmpty(cookies)) {
            for (Cookie cookie : cookies) {
                if (cookie.getName().equals(name)) {
                    return cookie.getValue();
                }
            }
        }
        return null;
    }


    /**
     * 删除Cookie
     *
     * @param name Cookie的名字
     */
    public void deleteCookie(String name) {
//        Cookie[] cookies = ServletHolderUtils.getCurRequest().getCookies();
//        HttpServletResponse res = ServletHolderUtils.getCurResponse();
//        if (!ArrayUtils.isEmpty(cookies)) {
//            for (Cookie cookie : cookies) {
//                if (cookie.getName().equals(name)) {
//                    cookie.setPath("/");
//                    cookie.setMaxAge(COOKIE_MIN_AGE);
//                    res.addCookie(cookie);
//                }
//            }
//        }
        addCookie(name, "", COOKIE_MIN_AGE);
    }

    /**
     * 获取登录的用户
     *
     * @return
     */
    public User getLoginUser() {
        String token = httpUtils.getCookie(COOKIE_TOKEN_NAME);
        if (null == token) {
            return null;
        }
        String key = REDIS_USER_PREFIX + token;
        if (!redisClient.exists(key)) {
            return null;
        } else {
            User user = redisClient.getObj(key);
            return user;
        }
    }
}